package main // 声明 main 包，表明当前是一个可执行程序

import (
	"encoding/json"
	"fmt" // 导入内置 fmt
)

func main() { // main函数，是程序执行的入口
	// fmt.Println("Hello World!")  // 在终端打印 Hello World!
	// x, _ := foo()
	// _, y := foo()
	// fmt.Println("x=", x)
	// fmt.Println("y=", y)
	// fmt.Println("str := \"c:\\pprof\\main.exe\"")

	// a := [2][3]int{{1, 2, 3}, {4, 5, 6}}
	// b := [...][2]int{{1, 1}, {2, 2}, {3, 3}} // 第 2 纬度不能用 "..."。

	// fmt.Println(a, b)

	// var arr1 [5]int
	// printArr(&arr1)
	// fmt.Println(arr1)
	// arr2 := [...]int{2, 4, 6, 8, 10}
	// printArr(&arr2)
	// fmt.Println(arr2)

	//        //1.声明切片
	//    var s1 []int
	//    if s1 == nil {
	//       fmt.Println("是空")
	//    } else {
	//       fmt.Println("不是空")
	//    }
	//    // 2.:=
	//    s2 := []int{}
	//    // 3.make()
	//    var s3 []int = make([]int, 0)
	//    fmt.Println(s1, s2, s3)

	// // 4.初始化赋值
	// var s4 []int = make([]int, 0, 0)
	// fmt.Println(s4)
	// s5 := []int{1, 2, 3}
	// fmt.Println(s5)
	// // 5.从数组切片
	// arr := [5]int{1, 2, 3, 4, 5}
	// var s6 []int
	// // 前包后不包
	// s6 = arr[1:4]
	// fmt.Println(s6)

	// var a = []int{1, 2, 3}
	// fmt.Printf("slice a : %v\n", a)
	// var b = []int{4, 5, 6}
	// fmt.Printf("slice b : %v\n", b)
	// c := append(a, b...)
	// fmt.Printf("%p\n", &c)
	// fmt.Printf("slice c : %v\n", c)
	// d := append(c, 7)
	// fmt.Printf("%p\n", &d)
	// fmt.Printf("slice d : %v\n", d)
	// e := append(d, 8, 9, 10)
	// fmt.Printf("slice e : %v\n", e)

	// data := [...]int{0, 1, 2, 3, 4, 9: 0}

	// s := data[:2:3]
	// fmt.Println(s, data,len(s),cap(s))

	// s = append(s, 100, 200) // 一次 append 两个值，超出 s.cap 限制

	// fmt.Println(s, data,len(s),cap(s))

	// s = append(s, 300, 400) // 一次 append 两个值，超出 s.cap 限制

	// fmt.Println(s, data,len(s),cap(s))

	// s1 := []int{1, 2, 3, 4, 5}
	// fmt.Printf("slice s1 : %v\n", s1)
	// s2 := make([]int, 10)
	// fmt.Printf("slice s2 : %v\n", s2)
	// copy(s1, s2)
	// fmt.Printf("copied slice s1 : %v\n", s1)
	// fmt.Printf("copied slice s2 : %v\n", s2)

	// data := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	// // slice := data[:]
	// for index, value := range data {
	//     fmt.Printf("inde : %v , value : %v\n", index, value)
	// }

	// var a = []int{1, 3, 4, 5}
	// fmt.Printf("slice a : %v , len(a) : %v\n", a, len(a))
	// fmt.Println("a[1] address: %p",&a[1])
	// b := a[1:2]
	// fmt.Printf("slice b : %v , len(b) : %v\n", b, len(b))
	// fmt.Println("b[0] address: %p",&b[0])
	// c := b[0:3]
	// fmt.Printf("slice c : %v , len(c) : %v\n", c, len(c))
	// fmt.Println("c[0] address: %p",&c[0])

	// var p *string
	// fmt.Println(p)
	// fmt.Printf("p的值是%s\n", p)
	// if p != nil {
	// 	fmt.Println("非空")
	// } else {
	// 	fmt.Println("空值")
	// }

	// var a *int
	// *a = 100
	// fmt.Println(*a)

	// var b map[string]int
	// b["测试"] = 100
	// fmt.Println(b)

	// a := new(int)
	// b := new(bool)
	// fmt.Printf("%T\n", a) // *int
	// fmt.Printf("%T\n", b) // *bool
	// fmt.Println(*a)       // 0
	// fmt.Println(*b)       // false

	// var a int
	// fmt.Println(&a)
	// var p *int
	// p = &a
	// *p = 20
	// fmt.Println(a)

	// scoreMap := make(map[string]int)
	// scoreMap["张三"] = 90
	// scoreMap["小明"] = 100
	// // 如果key存在ok为true,v为对应的值；不存在ok为false,v为值类型的零值
	// v, ok2222 := scoreMap["张三2"]

	// userInfo := map[string]string{
	// 	"username": "pprof.cn",
	// 	"password": "123456",
	// }
	// fmt.Println(userInfo)

	// if ok2222 {
	// 	fmt.Println(v)
	// } else {
	// 	fmt.Println("查无此人")
	// }

	// scoreMap := make(map[string]int)
	// scoreMap["张三"] = 90
	// scoreMap["小明"] = 100
	// scoreMap["王五"] = 60
	// // for k, v := range scoreMap {
	// // 	fmt.Println(k, ":", v)
	// // }
	// // for v := range scoreMap {
	// // 	fmt.Println(v)
	// // }
	// delete(scoreMap, "小明") //将小明:100从map中删除
	// for k, v := range scoreMap {
	// 	fmt.Println(k, v)
	// }

	// rand.Seed(time.Now().UnixNano()) //初始化随机数种子

	// var scoreMap = make(map[string]int, 200)

	// for i := 0; i < 100; i++ {
	// 	key := fmt.Sprintf("stu%02d", i) //生成stu开头的字符串
	// 	value := rand.Intn(100)          //生成0~99的随机整数
	// 	scoreMap[key] = value
	// }
	// //取出map中的所有key存入切片keys
	// var keys = make([]string, 0, 200)
	// for key := range scoreMap {
	// 	keys = append(keys, key)
	// }
	// //对切片进行排序
	// sort.Strings(keys)
	// //按照排序后的key遍历map
	// for _, key := range keys {
	// 	fmt.Println(key, scoreMap[key])
	// }

	// var mapSlice = make([]map[string]string, 3)
	// for index, value := range mapSlice {
	// 	fmt.Printf("index:%d value:%v\n", index, value)
	// }
	// fmt.Println("after init")
	// // 对切片中的map元素进行初始化
	// mapSlice[0] = make(map[string]string, 10)
	// mapSlice[0]["name"] = "王五"
	// mapSlice[0]["password"] = "123456"
	// mapSlice[0]["address"] = "红旗大街"
	// for index, value := range mapSlice {
	// 	fmt.Printf("index:%d value:%v\n", index, value)
	// }

	// var sliceMap = make(map[string][]string, 3)
	// fmt.Println(sliceMap)
	// fmt.Println("after init")
	// key := "中国"
	// value, _ := sliceMap[key]
	// // if !ok {
	// // 	value = make([]string, 0, 1)
	// // }
	// value = append(value, "北京", "上海")
	// sliceMap[key] = value
	// fmt.Println(sliceMap, cap(value))

	// var p2 = new(person)
	// p2.name = "测试"
	// p2.age = 18
	// p2.city = "北京"
	// fmt.Printf("%T\n", p2)    //*main.person
	// fmt.Printf("p2=%v\n", p2) //p2=&main.person{name:"测试", city:"北京", age:18}

	// p3 := &person{}
	// fmt.Printf("%T\n", p3)     //*main.person
	// fmt.Printf("p3=%#v\n", p3) //p3=&main.person{name:"", city:"", age:0}
	// p3.name = "博客"
	// p3.age = 30
	// p3.city = "成都"
	// fmt.Printf("p3=%#v\n", p3) //p3=&main.person{name:"博客", city:"成都", age:30}

	// var p4 person
	// fmt.Printf("p4=%#v\n", p4) //p4=main.person{name:"", city:"", age:0}

	// p5 := person{
	// 	name: "pprof.cn",
	// 	city: "北京",
	// 	age:  18,
	// }
	// fmt.Printf("p5=%#v\n", p5) //p5=main.person{name:"pprof.cn", city:"北京", age:18}

	// p6 := &person{
	// 	name: "pprof.cn",
	// 	city: "北京",
	// 	age:  18,
	// }
	// fmt.Printf("p6=%#v\n", p6) //p6=&main.person{name:"pprof.cn", city:"北京", age:18}

	// p7 := &person{
	// 	city: "北京",
	// }
	// fmt.Printf("p7=%#v\n", p7) //p7=&main.person{name:"", city:"北京", age:0}

	// p8 := &person{
	// 	"pprof.cn",
	// 	"北京",
	// 	18,
	// }
	// fmt.Printf("p8=%#v\n", p8) //p8=&main.person{name:"pprof.cn", city:"北京", age:18}

	// m := make(map[string]*student)
	// stus := []student{
	// 	{name: "pprof.cn", age: 18},
	// 	{name: "测试", age: 23},
	// 	{name: "博客", age: 28},
	// 	{name: "changzifuchuan", age: 37},
	// }
	// // fmt.Println(stus)
	// // fmt.Println("stus地址：%p", &stus[0])

	// for _, stu := range stus {
	// 	fmt.Println("stu地址：%p", &stu)
	// 	m[stu.name] = &stu
	// 	fmt.Println("stu地址：%p", &stu.name)
	// 	fmt.Println("对象：", m[stu.name])

	// }
	// for k, v := range m {
	// 	fmt.Println(k, "=>", v)
	// }

	// p9 := newPerson("pprof.cn", "测试", 90)
	// fmt.Printf("%#v\n", p9)

	// p1 := newPerson("测试", "Su", 25)
	// p1.Dream()
	// p1.SetAge2(30)      // (*p1).SetAge2(30)
	// fmt.Println(p1.age) // 25

	// user1 := User{
	// 	Name:   "pprof",
	// 	Gender: "女",
	// 	Address: Address1{
	// 		Province: "黑龙江",
	// 		City:     "哈尔滨",
	// 	},
	// }
	// fmt.Printf("user1=%#v\n", user1) //user1=main.User{Name:"pprof", Gender:"女", Address:main.Address{Province:"黑龙江", City:"哈尔滨"}}

	// var user2 User2
	// user2.Name = "pprof,,"
	// user2.Gender = "女,,,"
	// user2.Address2.Province = "黑龙江,,," //通过匿名结构体.字段名访问
	// user2.Address2.City = "哈尔滨,,,"     //直接访问匿名结构体的字段名
	// fmt.Printf("user2=%#v\n", user2)   //user2=main.User{Name:"pprof", Gender:"女", Address:main.Address{Province:"黑龙江", City:"哈尔滨"}}

	// var ce []student1 //定义一个切片类型的结构体
	// ce = []student1{
	// 	student1{1, "xiaoming", 22},
	// 	student1{2, "xiaozhang", 33},
	// }
	// fmt.Println(ce)
	// demo(ce)
	// fmt.Println(ce)
	// ce := make(map[int]student1)
	// ce[1] = student1{1, "xiaolizi", 22}
	// ce[2] = student1{2, "wang", 23}
	// fmt.Println(ce)
	// delete(ce, 2)
	// fmt.Println(ce)

	c := &Class{
		Title:    "101",
		Students: make([]*Student, 0, 200),
	}
	for i := 0; i < 10; i++ {
		stu := &Student{
			Name:   fmt.Sprintf("stu%02d", i),
			Gender: "男",
			ID:     i,
		}
		c.Students = append(c.Students, stu)
	}
	//JSON序列化：结构体-->JSON格式的字符串
	data, err := json.Marshal(c)
	if err != nil {
		fmt.Println("json marshal failed")
		return
	}
	fmt.Printf("json:%s\n", data)
	//JSON反序列化：JSON格式的字符串-->结构体
	str := `{"Title":"101","Students":[{"ID":0,"Gender":"男","Name":"stu00"},{"ID":1,"Gender":"男","Name":"stu01"},{"ID":2,"Gender":"男","Name":"stu02"},{"ID":3,"Gender":"男","Name":"stu03"},{"ID":4,"Gender":"男","Name":"stu04"},{"ID":5,"Gender":"男","Name":"stu05"},{"ID":6,"Gender":"男","Name":"stu06"},{"ID":7,"Gender":"男","Name":"stu07"},{"ID":8,"Gender":"男","Name":"stu08"},{"ID":9,"Gender":"男","Name":"stu09"}]}`
	c1 := &Class{}
	err = json.Unmarshal([]byte(str), c1)
	if err != nil {
		fmt.Println("json unmarshal failed!")
		return
	}
	fmt.Printf("%#v\n", c1)
	fmt.Printf("%#v\n", c1.Students[2].Name)
}

// Class 班级
type Class struct {
	Title    string
	Students []*Student
}

// Student 学生
type Student struct {
	ID     int
	Gender string
	Name   string
}

func demo(ce []student1) {
	//切片是引用传递，是可以改变值的
	ce[1].age = 999
	// ce = append(ce, student{3, "xiaowang", 56})
	// return ce
}

type student1 struct {
	id   int
	name string
	age  int
}

// Address 地址结构体
type Address2 struct {
	Province string
	City     string
}

// User 用户结构体
type User2 struct {
	Name     string
	Gender   string
	Address2 //匿名结构体
}

// Address 地址结构体
type Address1 struct {
	Province string
	City     string
}

// User 用户结构体
type User struct {
	Name    string
	Gender  string
	Address Address1
}

// SetAge2 设置p的年龄
// 使用值接收者
func (p *person) SetAge2(newAge int8) {
	p.age = newAge
}

func (p person) Dream() {
	fmt.Printf("%#v的梦想是学好Go语言！\n", p)
}

func newPerson(name, city string, age int8) *person {
	return &person{
		name: name,
		city: city,
		age:  age,
	}
}

type person struct {
	name string
	city string
	age  int8
}

type student struct {
	name string
	age  int
}

func foo() (int, string) {
	return 10, "Q1mi"
}

func printArr(arr *[5]int) {
	arr[0] = 10
	for i, v := range arr {
		fmt.Println(i, v)
	}
}
